import logging
import re
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from visitor.auth import VisitorJWT
from ymiot import views as ymiotapi
from sms import views as smsapi
from cars.models import Car
from mgmt.models import Security
from mgmt.serializers import SecuritySerl
from mgmt import pagination
from persons.models import Person
from persons.serializers import PersonLstSerl
from visitor.models import VisitorModel, VisitorTeacher
from visitor.serializers import VisitorSerl, VisitorTeacherSerl
from visitor.models import VisitorApply
from visitor.serializers import VisitorApplyDetSerl
from visitor.models import VisitorApplyCar
from visitor.serializers import VisitorApplyCarSerl
from visitor.models import VisitorApplyPerson
from visitor.serializers import VisitorApplyPersonSerl
from visitor.models import VisitorCar
from visitor.serializers import VisitorCarSerl
from visitor.models import VisitorPerson
from visitor.serializers import VisitorPersonSerl
from visitor.models import VisitorApplyVerify
from teacher.models import TeacherModel
from teacher.serializers import TeacherBriefSerl, TeacherSerl,TeacherBriefNoPhoneSerl


logger = logging.getLogger("log")


class RegApi(APIView):

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        openid = request.data["openid"]
        phone = request.data["phone"]
        name = request.data["name"]
        dept = request.data["dept"]
        try:
            visitor = VisitorModel.objects.get(phone=phone)
        except VisitorModel.DoesNotExist:
            visitor = VisitorModel()
            visitor.phone = phone
        visitor.openid = openid
        visitor.name = name
        visitor.dept = dept
        try:
            visitor.save()
            logger.info(f"接口>>>访客>>>{visitor.name}>>>注册成功")
        except Exception as e:
            print(e)
            result["code"] = 500
            result["msg"] = "保存失败"
        return Response(result)


class IndexDataApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        result["data"]["visitor"] = VisitorSerl(request_visitor).data
        # 安全等级
        security = Security.objects.get(pk=1)
        result["data"]["security"] = SecuritySerl(security).data
        # 正在进行的申请
        STATUS_CHOISE = (
            (0, "被访者审核中"),
            (1, "上级审核中"),
            (2, "保卫处审核中"),
            (5, "审核完成"),
            (6, "审核失败"),
            (7, "访问中"),
            (8, "完成访问"),
            (9, "访问过期"),
        )
        visitor_apply_list = (
            VisitorApply.objects.filter(visitor=request_visitor)
            .exclude(status__gte=8)
            .exclude(status=6)
        )
        if visitor_apply_list.count() == 0:
            result["data"]["applyFlag"] = 0
        else:
            result["data"]["applyFlag"] = 1
            result["data"]["apply"] = VisitorApplyDetSerl(
                visitor_apply_list.last()
            ).data
            apply_person_list = VisitorApplyPerson.objects.filter(
                apply=visitor_apply_list.last()
            )
            if apply_person_list.count() == 0:
                result["data"]["applyPersonFlag"] = 0
            else:
                result["data"]["applyPersonFlag"] = 1
                result["data"]["applyPersonList"] = VisitorApplyPersonSerl(
                    apply_person_list, many=True
                ).data
            apply_car_list = VisitorApplyCar.objects.filter(
                apply=visitor_apply_list.last()
            )
            if apply_car_list.count() == 0:
                result["data"]["applyCarFlag"] = 0
            else:
                result["data"]["applyCarFlag"] = 1
                result["data"]["applyCarList"] = VisitorApplyCarSerl(
                    apply_car_list, many=True
                ).data
        return Response(result)


class TeacherListApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        visitor_teacher_list = VisitorTeacher.objects.filter(
            visitor=request_visitor
        ).order_by("order")[:5]
        teacherList = []
        for visitor_teacher in visitor_teacher_list:
            teacherItem = {}
            teacherItem["id"] = visitor_teacher.teacher.id
            teacherItem["name"] = visitor_teacher.teacher.name
            teacherItem["dept"] = visitor_teacher.teacher.dept
            teacherList.append(teacherItem)
        result["data"]["teacherList"] = teacherList
        return Response(result)


class TeacherSearchApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        name = request.GET.get("name")
        print(name)
        pattern = r"^[\u4e00-\u9fa5]{2,10}$"
        if re.match(pattern, name):
            teacherLst = TeacherModel.objects.filter(name__contains=name)[:10]
        else:
            return Response({"code": 500, "msg": "参数错误"})
        result["data"]["searchList"] = TeacherBriefNoPhoneSerl(teacherLst, many=True).data
        return Response(result)


class PersonListApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        # 是否已经是人员
        try:
            person = Person.objects.get(phone=request_visitor.phone)
        except Person.DoesNotExist:
            person = Person()
            person.name = request_visitor.name
            person.dept = request_visitor.dept
            person.phone = request_visitor.phone
            person.save()
        addPersonList = [
            {
                "uuid": person.uuid,
                "name": person.name,
                "phone": person.phone,
            }
        ]
        result["data"]["addPersonList"] = addPersonList
        visitor_person_list = VisitorPerson.objects.filter(visitor=request_visitor).order_by("order")[:5]
        visitorPersonList = []
        for visitor_person in visitor_person_list:
            visitorPersonItem = {}
            visitorPersonItem["id"] = visitor_person.id
            visitorPersonItem["uuid"] = visitor_person.person.uuid
            visitorPersonItem["name"] = visitor_person.person.name
            visitorPersonItem["phone"] = visitor_person.person.phone
            visitorPersonList.append(visitorPersonItem)
        result["data"]["visitorPersonList"] = visitorPersonList
        return Response(result)


class PersonSearchApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        phone = request.GET.get("phone")
        try:
            person = Person.objects.get(phone=phone)
            result["data"]["oldPerson"] = PersonLstSerl(person).data
        except Person.DoesNotExist:
            result["code"] = 404
            result["msg"] = "未找到该用户"
        return Response(result)


class PersonAddApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        dept = request.data["dept"]
        phone = request.data["phone"]
        name = request.data["name"]
        try:
            person = Person.objects.get(phone=phone)
        except Person.DoesNotExist:
            person = Person()
            person.phone = phone
            person.name = name
            person.dept = dept
            person.save()
        if not VisitorPerson.objects.filter(
            visitor=request_visitor, person=person
        ).exists():
            visitor_person = VisitorPerson()
            visitor_person.person = person
            visitor_person.visitor = request_visitor
            visitor_person.save()
        result["data"]["addPerson"] = {
            "uuid": person.uuid,
            "name": person.name,
            "phone": person.phone,
        }
        return Response(result)


class PersonBindApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        uuid = request.data["uuid"]
        try:
            person = Person.objects.get(uuid=uuid)
        except Person.DoesNotExist:
            result["code"] = 404
            result["msg"] = "未找到该用户"
            return Response(result)
        if not VisitorPerson.objects.filter(
            visitor=request_visitor, person=person
        ).exists():
            visitor_person = VisitorPerson()
            visitor_person.person = person
            visitor_person.visitor = request_visitor
            visitor_person.save()
        result["data"]["bindPerson"] = {
            "uuid": person.uuid,
            "name": person.name,
            "phone": person.phone,
        }
        return Response(result)


class CarListApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        visitor_car_list = VisitorCar.objects.filter(visitor=request_visitor).order_by("order")[:5]
        visitorCarList = []
        for visitor_car in visitor_car_list:
            visitorCarItem = {}
            visitorCarItem["id"] = visitor_car.id
            visitorCarItem["carId"] = visitor_car.car.id
            visitorCarItem["plate"] = visitor_car.car.plate
            visitorCarItem["status"] = visitor_car.car.status
            visitorCarList.append(visitorCarItem)
        result["data"]["visitorCarList"] = visitorCarList
        return Response(result)


class CarSearchApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        plate = request.GET.get("plate")
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            car = Car()
            car.plate = plate
            car.save()
        # 绑定
        if not VisitorCar.objects.filter(visitor=request_visitor, car=car).exists():
            visitor_car = VisitorCar()
            visitor_car.car = car
            visitor_car.visitor = request_visitor
            visitor_car.save()
        result["data"]["newCar"] = {
            "id": car.id,
            "plate": car.plate,
            "status": car.status,
            "status_text": car.get_status_display(),
        }
        return Response(result)


class CarAddApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        plate = request.data["plate"]
        try:
            car = Car.objects.get(plate=plate)
        except Car.DoesNotExist:
            car = Car()
            car.plate = plate
            car.save()
        if not VisitorCar.objects.filter(visitor=request_visitor, car=car).exists():
            visitor_car = VisitorCar()
            visitor_car.car = car
            visitor_car.visitor = request_visitor
            visitor_car.save()
        result["data"]["addCar"] = {"id": car.id, "car": car.plate}
        return Response(result)


class CarBindApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        car_id = request.data["car_id"]
        try:
            car = Car.objects.get(id=car_id)
        except Car.DoesNotExist:
            result["code"] = 404
            result["msg"] = "未找到该用户"
            return Response(result)
        if not VisitorCar.objects.filter(visitor=request_visitor, car=car).exists():
            visitor_car = VisitorCar()
            visitor_car.car = car
            visitor_car.visitor = request_visitor
            visitor_car.save()
        result["data"]["bindCar"] = {"id": car.id, "car": car.plate}
        return Response(result)


class ApplyAddApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        teacher_id = request.data["teacher_id"]
        teacher = TeacherModel.objects.get(id=teacher_id)
        when = request.data["when"]
        what = request.data["what"]
        isfree = request.data["isfree"]
        person_list = request.data["person_list"]
        # print("person_list:", person_list)
        car_list = request.data["car_list"]
        # print("car_list:", car_list)
        # # 判断车辆是否已经入场
        # try:
        #     car_list = request.data["car_list"]
        #     for carItm in carLst:
        #         car = Car.objects.get(id=carItm["id"])
        #         if car.status == 3:
        #             msg = "车辆" + car.plate + "已在场内，无法再次申请"
        #             ret = {"code": 500, "msg": msg}
        #             return Response(ret)
        # except Exception:
        #     pass
        # 判断本访客是否有在进行的访问
        visitor_apply_list = (
            VisitorApply.objects.filter(visitor=request_visitor)
            .exclude(status__gte=8)
            .exclude(status=6)
        )
        if visitor_apply_list.count() > 0:
            msg = "本访客有进行中的访问，无法再次申请"
            ret = {"code": 500, "msg": msg}
            return Response(ret)
        # 创建申请
        apply = VisitorApply()
        apply.visitor = request_visitor
        apply.teacher = teacher
        apply.when = when
        apply.what = what
        apply.isfree = isfree
        apply.save()
        # 1.处理教师
        # 1.1 绑定教师
        if not VisitorTeacher.objects.filter(
            visitor=request_visitor, teacher=teacher
        ).exists():
            visitor_teacher = VisitorTeacher()
            visitor_teacher.teacher = teacher
            visitor_teacher.visitor = request_visitor
            visitor_teacher.save()
        else:
            visitor_teacher = VisitorTeacher.objects.filter(
                visitor=request_visitor, teacher=teacher
            ).last()
        # 1.2 增加order
        visitor_teacher.order = visitor_teacher.order + 1
        visitor_teacher.save()
        # 2.处理人员
        for person_item in person_list:
            person = Person.objects.get(uuid=person_item["uuid"])
            # 2.1 加入申请
            if not VisitorApplyPerson.objects.filter(
                apply=apply, person=person
            ).exists():
                visitor_apply_person = VisitorApplyPerson()
                visitor_apply_person.apply = apply
                visitor_apply_person.person = person
                visitor_apply_person.save()
            # 2.2 处理人员状态
            person.status = 1
            person.save()
            # 2.3 处理人员绑定
            if not VisitorPerson.objects.filter(
                visitor=request_visitor, person=person
            ).exists():
                visitor_person = VisitorPerson()
                visitor_person.person = person
                visitor_person.visitor = request_visitor
                visitor_person.save()
            else:
                visitor_person = VisitorPerson.objects.filter(
                    visitor=request_visitor, person=person
                ).last()
            # 2.4 增加order
            visitor_person.order = visitor_person.order + 1
            visitor_person.save()
        # 3.处理车辆
        for car_item in car_list:
            car = Car.objects.get(id=car_item["id"])
            # 3.1 加入申请
            if not VisitorApplyCar.objects.filter(apply=apply, car=car).exists():
                visitor_apply_car = VisitorApplyCar()
                visitor_apply_car.apply = apply
                visitor_apply_car.car = car
                visitor_apply_car.save()
            # 3.2 处理车辆状态
            car.status = 1
            car.save()
            # 3.3 处理车辆绑定
            if not VisitorCar.objects.filter(visitor=request_visitor, car=car).exists():
                visitor_car = VisitorCar()
                visitor_car.car = car
                visitor_car.visitor = request_visitor
                visitor_car.save()
            else:
                visitor_car = VisitorCar.objects.filter(
                    visitor=request_visitor, car=car
                ).last()
            # 3.4 增加车辆order
            visitor_car.order = visitor_car.order + 1
            visitor_car.save()
        # 处理申请审核
        visitor_apply_verify = VisitorApplyVerify()
        visitor_apply_verify.stage = apply.status
        visitor_apply_verify.apply = apply
        visitor_apply_verify.teacher = teacher
        visitor_apply_verify.save()
        # 处理短信
        smsvars = {
            "source": "访客{}".format(apply.visitor.name),
        }
        smsapi.send_sms(1, teacher.phone, smsvars)
        # 处理日志
        logger.info(
            "访问教师{}申请访客{}，申请ID：{}-提交成功".format(
                teacher.name, apply.visitor.name, apply.id
            )
        )
        return Response(result)


from django.shortcuts import get_object_or_404
from django.db import transaction


class ApplyDelApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def post(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        apply_id = request.data.get("apply_id")
        if not apply_id:
            return Response({"code": 400, "msg": "缺少参数 apply_id"})
        # 权限控制：确保当前用户只能操作自己的记录
        visitor_apply = get_object_or_404(VisitorApply, id=apply_id, visitor=request.user)
        try:
            with transaction.atomic():
                visitor_apply.status = 10
                visitor_apply.save()
                for person_link in VisitorApplyPerson.objects.filter(apply=visitor_apply):
                    person_link.person.status = 0
                    person_link.person.save()
                for car_link in VisitorApplyCar.objects.filter(apply=visitor_apply):
                    car = car_link.car
                    if car.status == 2:
                        try:
                            response_del = ymiotapi.del_visitor_car(car.visitor_no, car.plate)
                            print(f"车辆 {car.plate} 清除状态结果: {response_del}")
                        except Exception as e:
                            print(f"车辆 {car.plate} 清除状态异常: {e}")
                    car.status = 0
                    car.save()
        except Exception as e:
            return Response({"code": 500, "msg": f"服务器错误: {str(e)}"})
        return Response(result)



class ApplyDetApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        apply_id = request.GET.get("apply_id")
        try:
            visitor_apply = VisitorApply.objects.get(id=apply_id)
        except VisitorApply.DoesNotExist:
            msg = "访问申请ID：{}-提交失败，访问申请不存在"
            ret = {"code": 500, "msg": msg}
            return Response(ret)
        request_visitor = request.user
        if visitor_apply.visitor != request_visitor:
            msg = "访问申请ID：{}-提交失败，访问申请与访问用户不匹配"
            ret = {"code": 500, "msg": msg}
            return Response(ret)
        # 返回申请信息
        result["data"]["apply"] = VisitorApplyDetSerl(visitor_apply).data
        # 处理人员信息
        main_person = Person.objects.get(phone=visitor_apply.visitor.phone)
        apply_person_list = VisitorApplyPerson.objects.filter(
            apply=visitor_apply
        ).exclude(person=main_person)
        if apply_person_list.count() == 0:
            result["data"]["applyPersonFlag"] = 0
        else:
            result["data"]["applyPersonFlag"] = 1
            result["data"]["applyPersonLst"] = VisitorApplyPersonSerl(
                apply_person_list, many=True
            ).data
        # 处理车辆信息
        apply_car_list = VisitorApplyCar.objects.filter(apply=visitor_apply)
        if apply_car_list.count() == 0:
            result["data"]["applyCarFlag"] = 0
        else:
            result["data"]["applyCarFlag"] = 1
            result["data"]["applyCarLst"] = VisitorApplyCarSerl(
                apply_car_list, many=True
            ).data
        return Response(result)


class ApplyLstApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        result["data"]["visitor"] = VisitorSerl(request_visitor).data
        # 申请
        visitor_apply_list = VisitorApply.objects.filter(
            visitor=request_visitor
        ).order_by("-updated")
        apply_list = []
        for visitor_apply in visitor_apply_list:
            apply_item = {}
            apply_item["id"] = visitor_apply.id
            apply_item["visitor"] = visitor_apply.visitor.name
            apply_item["visitorDept"] = visitor_apply.visitor.dept
            apply_item["visitorPhone"] = visitor_apply.visitor.phone
            apply_item["status"] = visitor_apply.status
            apply_item["statusText"] = visitor_apply.get_status_display()
            apply_item["when"] = visitor_apply.when.strftime("%m-%d %H:%M")
            apply_item["teacherId"] = visitor_apply.teacher.id
            apply_item["teacherDept"] = visitor_apply.teacher.dept
            apply_item["teacherName"] = visitor_apply.teacher.name
            apply_item["teacherPhone"] = visitor_apply.teacher.phone
            apply_list.append(apply_item)
        # 1. 实例化分页器对象
        page_obj = pagination.PageNumberPagination()
        # 2. 使用自己配置的分页器调用分页方法进行分页
        page_data = page_obj.paginate_queryset(apply_list, request)
        # 4. 返回带上一页/下一页连接的页面
        return page_obj.get_paginated_response(page_data)


class InfoIndexApi(APIView):
    permission_classes = (IsAuthenticated,)
    authentication_classes = [VisitorJWT]

    def get(self, request, format=None):
        result = {"code": 0, "msg": "ok", "data": {}}
        request_visitor = request.user
        result["data"]["visitor"] = VisitorSerl(request_visitor).data
        # 安全等级
        security = Security.objects.get(pk=1)
        result["data"]["security"] = SecuritySerl(security).data
        # 访问申请列表
        visitor_apply_list = VisitorApply.objects.filter(
            visitor=request_visitor
        ).order_by("-updated")
        result["data"]["applyCount"] = visitor_apply_list.count()
        visitor_apply_list = visitor_apply_list[:5]
        apply_list = []
        for visitor_apply in visitor_apply_list:
            apply_item = {}
            apply_item["id"] = visitor_apply.id
            apply_item["status"] = visitor_apply.status
            apply_item["statusText"] = visitor_apply.get_status_display()
            apply_item["teacher"] = visitor_apply.teacher.name
            apply_item["when"] = visitor_apply.when.strftime("%m-%d %H:%M")
            # car
            apply_item["carCount"] = VisitorApplyCar.objects.filter(
                apply=visitor_apply
            ).count()
            # visitor
            apply_item["personCount"] = VisitorApplyPerson.objects.filter(
                apply=visitor_apply
            ).count()
            apply_list.append(apply_item)
        result["data"]["applyList"] = apply_list
        return Response(result)
